package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.example.domain.ResponseResult;
import org.example.domain.dto.SpotListDto;
import org.example.domain.entity.City;
import org.example.domain.entity.Spot;
import org.example.domain.vo.HomeHotSpotsVo;
import org.example.domain.vo.PageVo;
import org.example.domain.vo.SpotDetailVo;
import org.example.mapper.CityMapper;
import org.example.mapper.SpotMapper;
import org.example.service.SpotService;
import org.example.utils.BeanCopyUtils;
import org.example.utils.RedisCache;
import org.example.utils.SecurityUtils;
import org.springframework.stereotype.Service;

import java.util.List;


@Service
@RequiredArgsConstructor
public class SpotServiceImpl extends ServiceImpl<SpotMapper, Spot> implements SpotService {

    private final SpotMapper spotMapper;

    private final CityMapper cityMapper;

    private final RedisCache redisCache;
    @Override
    public ResponseResult addSpot(Spot spot) {
        Integer id = SecurityUtils.getUserId();
        spot.setCreateBy(id);
        return ResponseResult.okResult(save(spot));
    }

    @Override
    public ResponseResult spotList(SpotListDto spotListDto) {

        LambdaQueryWrapper<Spot> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(spotListDto.getSpotName()),Spot::getSpotName,spotListDto.getSpotName());
        if(spotListDto.getStatus() != null){
            queryWrapper.eq(Spot::getStatus,spotListDto.getStatus());
        }
        if(spotListDto.getCityId() != null){
            queryWrapper.eq(Spot::getCityId,spotListDto.getCityId());
        }

        Page<Spot> page = new Page<>();
        page.setSize(spotListDto.getPageSize());
        page.setCurrent(spotListDto.getPageNum());
        page(page,queryWrapper);

        PageVo pageVo = new PageVo(page.getRecords(),page.getTotal());

        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult updateSpot(Spot spot) {
        Integer id = SecurityUtils.getUserId();
        spot.setUpdateBy(id);
        return ResponseResult.okResult(updateById(spot));
    }

    @Override
    public ResponseResult hotSpots() {
        LambdaQueryWrapper<Spot> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Spot::getStatus,0);
        queryWrapper.orderByAsc(Spot::getViewCount);
        Page<Spot> page = new Page<>(1,6);
        page(page,queryWrapper);
        List<Spot> spots = page.getRecords();

        for(Spot spot : spots){
            if(spot.getCityId() == null){
                continue;
            }
            City city = cityMapper.getById(spot.getCityId());
            if(city == null) {
                continue;
            }
            spot.setCityName(city.getCityName());
        }
        List<HomeHotSpotsVo> homeHotSpotsVos = BeanCopyUtils.copyBeanList(spots, HomeHotSpotsVo.class);

        return ResponseResult.okResult(homeHotSpotsVos);

    }

    @Override
    public ResponseResult getSpotList(SpotListDto spotListDto) {
        LambdaQueryWrapper<Spot> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Spot::getStatus,0);
        if(spotListDto.getCityId() !=null && spotListDto.getCityId()>0){
            queryWrapper.eq(Spot::getCityId,spotListDto.getCityId());
        }
        Page<Spot> page = new Page<>();
        page.setCurrent(spotListDto.getPageNum());
        page.setSize(spotListDto.getPageSize());
        page(page,queryWrapper);
        PageVo pageVo = new PageVo(page.getRecords(),page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult updateViewCount(Integer id) {
        redisCache.incrementCacheMapValue("SpotViewCount",id.toString(),1);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getSpotDetail(Integer id) {
        Spot spot = getById(id);
        Integer spotViewCount = redisCache.getCacheMapValue("SpotViewCount", id.toString());
        spot.setViewCount(spotViewCount);
        SpotDetailVo spotDetailVo = BeanCopyUtils.copyBean(spot, SpotDetailVo.class);
        return ResponseResult.okResult(spotDetailVo);
    }
}
